﻿// -----------------------------------------------------------------------
// <copyright file="Response.cs" company="Softserve">
// Response
// Made by VK
// </copyright>
// -----------------------------------------------------------------------
namespace WebServer.BusinessLogic
{
    using System;
    using System.Text;
    using WebServer.BusinessLogic.Web;

    /// <summary>
    /// Response is responsible to serve data needed for RequestBuilder and Communicator to create a reply of our webserver for internet browser
    /// </summary>
    public class Response
    {
        /// <summary>
        ///  Initializes a new instance of the <see cref="Response" /> class.
        /// </summary>
        public Response()
        {
            this.Data = null;
            this.HttpVersion = Helpers.WebserverConstants.HttpVersion10;
            this.HttpResponseCode = 200;
            this.HttpResponseCodeDescription = "OK";
            this.Cookies = new WebsiteCookies();
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="Response" /> class.
        /// Constructor that should initialiaze all values that can have a setter
        /// </summary>
        /// <param name="mimeType">MimeType of the data</param>
        /// <param name="httpVersion">Version, HTTP/1.0 or HTTP/1.1</param>
        /// <param name="data">Byte array of data to respond with in body</param>
        public Response(string mimeType, string httpVersion, byte[] data) : this()
        {
            this.MimeType = mimeType;
            this.HttpVersion = httpVersion;
            this.Data = data;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="Response" /> class.
        /// </summary>
        /// <param name="request">http request</param>
        public Response(Request request) : this()
        {
            this.MimeType = "text/html";
            this.HttpVersion = request.HttpVersion;
        }

        /// <summary>
        /// Enum for redirect
        /// </summary>
        public enum RedirectMethodEnum
        {
            /// <summary>
            /// Temporary redirect
            /// </summary>
            Temporary
        }

        /// <summary>
        /// Gets or sets bytes of the Data that are needed to be responded with
        /// </summary>
        public byte[] Data { get; /*private*/ set; }

        /// <summary>
        /// Gets or sets mime type of file, for example: "text/html" or "image/gif"
        /// </summary>
        public string MimeType { get; /*private*/ set; }

        /// <summary>
        /// Gets or sets version of the HTTP protocol. Either HTTP/1.0 OR HTTP/1.1
        /// </summary>
        public string HttpVersion { get; /*private*/ set; }

        /// <summary>
        /// Gets or sets Hostname, for example: www.google.com
        /// </summary>
        public string Host { get; set; }

        /// <summary>
        /// Gets or sets bytes of the data webserver is returning to the client, start position
        /// </summary>
        public long RangeStart { get; set; }

        /// <summary>
        /// Gets or sets HTTP Response code. Default "200"
        /// </summary>
        public int HttpResponseCode { get; set; }

        /// <summary>
        /// Gets or sets HTTP Response description for the code. Default "OK"
        /// </summary>
        public string HttpResponseCodeDescription { get; set; }

        /// <summary>
        /// Gets or sets Connection status. Can be "close" or empty
        /// </summary>
        public string ConnectionStatus { get; set; }

        /// <summary>
        /// Gets or sets Last modified date of file. Handler should set this value
        /// </summary>
        public DateTime LastModified { get; set; }

        /// <summary>
        /// Gets or sets a value indicating whether if Response Accepts ranges. true will set Accept-Range header to "bytes", false to "none"
        /// </summary>
        public bool AcceptsRanges { get; set; }

        /// <summary>
        /// Gets or sets Encoding of responce content
        /// </summary>
        public string ContentEncoding { get; set; }

        /// <summary>
        /// Gets or sets Set-Cookie cookies
        /// </summary>
        public WebsiteCookies Cookies { get; set; }

        /// <summary>
        /// Gets or sets the Location path
        /// If set, initiates redirect to the Location path
        /// </summary>
        public string Location { get; set; }

        /// <summary>
        /// Set redirect to response
        /// </summary>
        /// <param name="location">path location</param>
        /// <param name="redirectMethod">redirect Method</param>
        public void SetRedirect(string location, RedirectMethodEnum redirectMethod)
        {
            this.Location = location;
            switch (redirectMethod)
            {
                case RedirectMethodEnum.Temporary:
                    this.HttpResponseCode = 302;
                    this.HttpResponseCodeDescription = "Found";
                    break;
            }
        }

        /// <summary>
        /// Creates 302 Found temporary redirect
        /// </summary>
        /// <param name="location">redirect location</param>
        public void SetRedirect(string location)
        {
            this.SetRedirect(location, RedirectMethodEnum.Temporary);
        }

        /// <summary>
        /// Settings httpResponse = 500 when server errors happen
        /// </summary>
        public void SetServerError()
        {
            this.HttpResponseCode = 500;
            this.HttpResponseCodeDescription = "Internal Server Error";
        }

        /// <summary>
        /// Setting acess denied
        /// </summary>
        public void SetAccessDenied()
        {
            this.HttpResponseCode = 401;
            this.HttpResponseCodeDescription = "Access Denied";
            this.Data = Encoding.UTF8.GetBytes("Access Denied");
        }
    }
}
